package com.rbac.modules.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rbac.modules.system.entity.SysPermission;
import com.rbac.modules.system.mapper.SysPermissionMapper;
import com.rbac.modules.system.service.SysPermissionService;
import com.rbac.modules.system.dto.PermissionDTO;
import com.rbac.modules.system.dto.PermissionQueryDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    private final SysPermissionMapper permissionMapper;

    @Override
    public Page<SysPermission> page(Page<SysPermission> page, PermissionQueryDTO query) {
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getPermissionName()), SysPermission::getPermissionName, query.getPermissionName())
               .like(StringUtils.hasText(query.getPermissionCode()), SysPermission::getPermissionCode, query.getPermissionCode())
               .eq(query.getPermissionType() != null, SysPermission::getPermissionType, query.getPermissionType())
               .eq(query.getStatus() != null, SysPermission::getStatus, query.getStatus())
               .orderByAsc(SysPermission::getSort);
        return page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PermissionDTO dto) {
        SysPermission permission = new SysPermission();
        BeanUtils.copyProperties(dto, permission);
        save(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PermissionDTO dto) {
        SysPermission permission = new SysPermission();
        BeanUtils.copyProperties(dto, permission);
        updateById(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        // 检查是否有子权限
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysPermission::getParentId, id);
        if (count(wrapper) > 0) {
            throw new RuntimeException("存在子权限，无法删除");
        }
        removeById(id);
    }

    @Override
    public List<SysPermission> listByRoleId(Long roleId) {
        return baseMapper.selectByRoleId(roleId);
    }

    @Override
    public List<SysPermission> listByUserId(Long userId) {
        return baseMapper.selectByUserId(userId);
    }

    @Override
    public List<SysPermission> tree() {
        // 获取所有权限
        List<SysPermission> allPermissions = list();
        
        // 构建树形结构
        Map<Long, List<SysPermission>> parentMap = allPermissions.stream()
                .collect(Collectors.groupingBy(SysPermission::getParentId));
        
        return buildTree(0L, parentMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer status) {
        SysPermission permission = new SysPermission();
        permission.setId(id);
        permission.setStatus(status);
        updateById(permission);
    }

    private List<SysPermission> buildTree(Long parentId, Map<Long, List<SysPermission>> parentMap) {
        List<SysPermission> children = parentMap.get(parentId);
        if (children == null) {
            return new ArrayList<>();
        }
        
        // 对子节点进行排序
        children.sort((a, b) -> a.getSort() - b.getSort());
        
        // 递归处理每个子节点
        for (SysPermission child : children) {
            List<SysPermission> grandChildren = buildTree(child.getId(), parentMap);
            if (!grandChildren.isEmpty()) {
                child.setChildren(grandChildren);
            }
        }
        
        return children;
    }

    @Override
    public boolean existsByCode(String code) {
        return lambdaQuery()
                .eq(SysPermission::getPermissionCode, code)
                .exists();
    }

    @Override
    public List<String> getPermissionCodesByUserId(Long userId) {
        return permissionMapper.getPermissionCodesByUserId(userId);
    }

    @Override
    public List<SysPermission> getCurrentUserPermissionTree() {
        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 获取用户的所有权限
        List<SysPermission> allPermissions = permissionMapper.getPermissionsByUserId(userId);
        
        // 只保留菜单类型的权限
        List<SysPermission> menuPermissions = allPermissions.stream()
                .filter(permission -> permission.getPermissionType() == 1)
                .collect(Collectors.toList());
        
        // 构建树形结构
        Map<Long, List<SysPermission>> parentMap = menuPermissions.stream()
                .collect(Collectors.groupingBy(SysPermission::getParentId));
        
        // 获取顶级菜单
        List<SysPermission> rootMenus = parentMap.getOrDefault(0L, new ArrayList<>());
        
        // 递归设置子菜单
        rootMenus.forEach(menu -> setChildren(menu, parentMap));
        
        return rootMenus;
    }

    /**
     * 递归设置子菜单
     */
    private void setChildren(SysPermission parent, Map<Long, List<SysPermission>> parentMap) {
        List<SysPermission> children = parentMap.get(parent.getId());
        if (children != null) {
            parent.setChildren(children);
            children.forEach(child -> setChildren(child, parentMap));
        }
    }
} 